from general_utilities import *
from graphics_utilities import *
from notifications import *
from sound import sound

class Condition:
  def __init__(self,d,id,type,end_turn):
    self.type = type
    self.id = id 
    self.end_turn = end_turn
    self.begin(d)
    
  def begin(self,d):
    # call when it first comes into force
    if self.no_energy_gain():
      d.get_entity(self.id).energy = min(d.get_entity(self.id).energy,0)
    
  def end(self,d,entity,quiet=0):
    # call when it is terminated by any means - called by expire()
    # base class does nothing
    pass
    
  def expire(self,d,display,entity):
    # call when it runs out naturally
    # base class only calls end()
    self.end(d,display,entity)
    
  def no_longer_here(self):
    # return 1 for conditions that mean the entity is no longer present in the dungeon
    return 0

  def is_dead(self):
    # return 1 for conditions that mean the entity is dead (neither unconscious nor escaped)
    return 0

  def has_escaped(self):
    # return 1 for conditions that mean the entity is no longer present in the dungeon (not dead or unconscious but safely escaped)
    return 0
  
  def no_energy_gain(self):
    # return 1 for conditions that mean the entity does not get energy and move
    return 0   
    
  def appears_incapacitated(self):
    # return 1 for conditions that means enemies see the entity as already incapacitated
    return 0
    
  def out_of_control(self):
    # return 1 for conditions that mean they are no longer loyal to their group
    return 0
  
  def get_type_string(self):
    # overload this for everything
    return ""

class Condition_defense(Condition):
  def get_type_string(self):
    if self.type==C_DEFENDING:
      return "DEFENDING"
    elif self.type==C_CIRCLE_OF_PROTECTION:
      return "PROTECTED"
    elif self.type==C_SNEAKING:
      return "SNEAKING"
    elif self.type==C_DODGING:
      return "DODGING"
    elif self.type==C_INVISIBLE:
      return "INVISIBLE"
    elif self.type==C_BLESSED:
      return "BLESSED"
    
  def expire(self,d,display,entity):
    # call when it runs out naturally
    if entity.is_character:
      if self.type==C_CIRCLE_OF_PROTECTION:
        display.send_message("The circle of protection has worn off!")
        sound.play('cancel1')
      if self.type==C_DODGING:
        display.send_message("Your hero is no longer dodging!")
        sound.play('cancel1')
      if self.type==C_STONESKIN:
        display.send_message("The stoneskin has worn off!")
        sound.play('cancel1')
      if self.type==C_FIRERES_FROM_SPELL or self.type==C_FIRERES_FROM_POTION:
        display.send_message("Your hero is less resistant to fire!")
        sound.play('cancel1')
      if self.type==C_CHAMELEON:
        display.send_message("Your hero's color returns to normal!")
        sound.play('cancel1')
      if self.type==C_AFRAID:
        display.send_message("Your hero has recovered his courage!")
    if self.type==C_BLESSED:
      n = Notification(entity.pos)
      n.set_sound('cancel1')
      n.set_message("The blessing on " + entity.name + " has worn off!",0)
      n.play(d)
    elif self.type==C_INVISIBLE:
      n = Notification(entity.pos)
      n.set_sound('cancel1')
      n.set_message(entity.name + " reappears!",0)
      n.play(d)
    self.end(d,display,entity)
    Condition.expire(self,d,display,entity)

  def end(self,d,display,entity,quiet=0):
    # call when it is terminated by any means - called by expire()
    if entity.is_character:
      if self.type==C_SNEAKING:
        display.send_message("Your hero is no longer sneaking!")
        sound.play('cancel1')
        # and then the caller updates display - cannot do here

class Condition_poisoned(Condition):
  def __init__(self,d,id,type,end_turn,level):
    Condition.__init__(self,d,id,type,end_turn)
    self.level = level # 1 is mild, 2 is severe

  def get_type_string(self):
    if self.level==1:
      return "POISONED (MILD)"
    elif self.level==2:
      return "POISONED (SEVERE)"
    
  def end(self,d,display,entity,quiet=0):
    # call when it is terminated by any means - called by expire()
    if entity.is_character:
      display.send_message("Your hero has recovered from poisoning.")

class Condition_left(Condition):
  # Parent of a number of conditions which basically remove the entity from the dungeon
  def no_longer_here(self):
    return 1 

  def no_energy_gain(self):
    return 1 

class Condition_dead(Condition_left):
  def is_dead(self):
    return 1 
 
  def get_type_string(self):
    return "DEAD"

class Condition_unconscious(Condition_left):
  def get_type_string(self):
    return "UNCONSCIOUS"

class Condition_escaped(Condition_left):
  def has_escaped(self):
    return 1 

  def get_type_string(self):
    return "ESCAPED"

class Condition_asleep(Condition):
  def no_energy_gain(self):
    return 1 

  def appears_incapacitated(self):
    return 1 
    
  def get_type_string(self):
    return "ASLEEP"

class Condition_paralysed(Condition_asleep):
  def get_type_string(self):
    return "PARALYSED"

class Condition_confused(Condition):
  def appears_incapacitated(self):
    return 1 
    
  def get_type_string(self):
    return "CONFUSED"  

class Condition_afraid(Condition):
  def appears_incapacitated(self):
    return 1 
    
  def get_type_string(self):
    return "TERRIFIED" 
  
  def out_of_control(self):
    return 1 
  
class Condition_charmed(Condition):
  # Parent of a number of conditions which make entities turn against their group
  
  def __init__(self,d,id,type,end_turn,charmer_group):
    Condition.__init__(self,d,id,type,end_turn)
    me = d.get_entity(self)
    self.original_attitude = me.attitude
    self.original_enemy_groups = me.enemy_groups
    if charmer_group==G_PARTY:
      me.attitude = A_FRIENDLY
      me.enemy_groups = []
    else:
      me.attitude = d.get_group(charmer_group).attitude
      me.enemy_groups = d.get_group(charmer_group).enemy_groups
    me.charmed_by = charmer_group   # not seen as an enemy
    
  def end(self,d,entity,quiet=0):
    me = d.get_entity(self)
    me.attitude = self.original_attitude
    me.enemy_groups = self.enemy_groups
    me.charmed_by = None
    Condition.end(self,d,display,entity)    

  def out_of_control(self):
    return 1 